package com.luomo.java.jvm.oom;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;

/**
 * java.lang.OutOfMemoryError: Metaspace
 *
 * JVM参数
 * -XX:MetaspaceSize=8m -XX:MaxMetaspaceSize=9m
 * <p>
 * Java8及之后的版本使用Metaspace替代永久代
 * <p>
 * Metaspace是方法区在HotSpot中的实现，它与持久代最大的区别在于：Metaspace并不在虚拟机内存中而是使用本地内存
 * 也即在Java8中，class metadata,被存储在叫做Metaspace的native memory
 * <p>
 * Metaspace存放信息：
 * 虚拟机加载的类信息
 * 常量池（字符串常量池在堆里）
 * 静态变量
 * 即时编译后的代码
 * <p>
 * 模拟Metaspace空间溢出，不断生成类往元空间，类占据的空间超过Metaspace大小就会报错
 *
 * @author LiuMei
 * @date 2021-04-15.
 */
public class MetaSpaceDemo {

    static class OOMTest {

    }

    public static void main(String[] args) {
        int i = 0;
        try {
            while (true) {
                i++;
                //通过动态代理模拟生成新的静态类
                Enhancer enhancer = new Enhancer();
                enhancer.setSuperclass(OOMTest.class);
                enhancer.setUseCache(false);
                enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> methodProxy.invokeSuper(o, args));
                enhancer.create();
            }
        } catch (Throwable e) {
            System.out.println("==================" + i);
            e.printStackTrace();
        }
    }

}
